#ifndef _TWITTER_OBJECT_H_
#define _TWITTER_OBJECT_H_
#include "twit4c/twit4c.h"
#include "twit/Value.h"

#ifndef __deprecated
#define __deprecated
#endif

NS_BEGIN(Twit)
class Twitter;
NS_BEGIN(Resource)

#define DeclareResourceClass(cls) \
class cls                        \
{                                   \
	friend class Twitter;            \
	~cls(){};                        
#define EndResourceClass }


template <typename T>
class Object:public CTwitUri
{
	response m_response;
	T* m_value;
	IOAuth& _o;
	RequestMethod m_reqMethod;
public:
	Object(IOAuth& o, const char* p, const char* f, ReturnFormat fmt=ReturnFormatJson,
		SchemeType scm=SchemeTypeHttp, RequestMethod rm=RequestMethodGet,
		const char* base=def_twit_url, size_t ver=def_twit_version):
	_o(o), m_reqMethod(rm), m_value(new T)
	{
		setBaseUrl(base);
		setPath(p);
		setFile(f);
		setReturnFormat(fmt);
		setSchemeType(scm);
		setVersion(ver);
	}
	~Object()
	{
		_DELETE(m_value);
	}

	void setRequestMethod(RequestMethod method)
	{
		m_reqMethod = method;
	}

	bool request()
	{
		_o.request(m_response, getUri(), m_reqMethod);
		if(m_response==true)
		{
			try
			{
				switch(getReturnFormat())
				{
				case ReturnFormatJson:
					Parser::Json::toValue(m_response.source(), *m_value);
					break;
				}
			}
			catch (Error& e)
			{
				m_response.set(e.getCode(), e.getMessage());      	
				return false;
			}
			return true;
		}
		else
		{
			if(m_response.getCode() == 503)
			{
				m_response.set(503,httpStatusCode2String(503));
			}
			else
				Parser::Json::parseError(m_response);
		}
		return false;
	}
	virtual T&   get()
	{
		if(request()==true)
		{
			return *m_value;
		}
		throw (Error)m_response;
	}
	inline const std::string& source(){ return m_response.source(); }
	inline const Error& getError() const { return m_response; }
	inline T& value() const
	{ 
		return *m_value; 
	}
};




#define __IncludeEntitiesCode { setParam("include_entities", v); }
template <typename T>
class TObjectStatuses:public Object<T>
{
public:
   TObjectStatuses(IOAuth& o, const char* file):Object<T>(o,"statuses",file)
   {
      setIncludeEntities(false);
      setTrimUser(false);
   }

   /**
   * @brief 
   *  When set to either true, t or 1, each tweet will include a node called "entities,". 
   *  This node offers a variety of metadata about the tweet in a discreet structure, 
   *  including: user_mentions, urls, and hashtags. While entities are opt-in on timelines at present, 
   *  they will be made a default component of output in the future. 
   *  See Tweet Entities(http://dev.Twitter.com/pages/tweet_entities) for more detail on entities.
   */
   void setIncludeEntities(bool v) __IncludeEntitiesCode

   /**
   * @brief 
   *  When set to either true, t or 1, each tweet returned in a timeline will include 
   *  a user Object including only the statuses authors numerical ID. 
   *  Omit this parameter to receive the complete user Object.
   */
   //void setTrimUser(bool bTrim)
   void setTrimUser(bool bTrim)
   {
      setParam("trim_user", bTrim);
   }
};

typedef TObjectStatuses<Value::Users> OStatusesVUsers;
typedef TObjectStatuses<Value::Statuses> OStatusesVStatuses;
#define __DoNotUse__
NS_END;
NS_END;
#endif /*_TWITTER_OBJECT_H_*/